import React, { Suspense, useState, useEffect, useRef } from "react";
import { Canvas } from "@react-three/fiber";
import { OrbitControls } from "@react-three/drei";
import * as THREE from "three";
import { PLYLoader } from "three/examples/jsm/loaders/PLYLoader";
// @ts-ignore
import actor1ply from "../asserts/actor1.ply";
import out from "../asserts/output.json";

function PlyModel({ url, frames }) {
  const [model, setModel] = useState(null);
  const frameIndex = useRef(0); // 用于跟踪当前帧索引
  const timeoutRef: any = useRef(); // 用于定时器的引用

  useEffect(() => {
    const loader = new PLYLoader();
    loader.load(url, (geometry) => {
      geometry.computeVertexNormals(); // 计算顶点法线以获得更好的光照效果
      const material = new THREE.MeshStandardMaterial({ color: "royalblue" });
      const mesh = new THREE.Mesh(geometry, material);
      setModel(mesh);
    });
  }, [url]);

  useEffect(() => {
    const updateFrame = () => {
      // console.log(model.geometry.attributes.position.array);
      if (!model || !frames || frameIndex.current >= frames.length) return;

      // 更新模型的顶点位置
      const currentFrame = frames[frameIndex.current];
      model.geometry.attributes.position.array = new Float32Array(
        currentFrame.flat()
      );
      model.geometry.attributes.position.needsUpdate = true;

      // 更新帧索引
      frameIndex.current = (frameIndex.current + 1) % frames.length;

      // 设置下一次更新
      timeoutRef.current = setTimeout(updateFrame, 100); // 1秒后更新下一帧
    };

    timeoutRef.current = setTimeout(updateFrame, 100); // 初始化定时器

    // 清理函数
    return () => {
      clearTimeout(timeoutRef.current);
    };
  }, [model, frames]);

  const scaleSize = 0.3; // 定义放大倍数
  return model ? (
    <primitive
      object={model}
      scale={new THREE.Vector3(scaleSize, scaleSize, scaleSize)}
    />
  ) : null;
}

function PlyDemo3() {
  console.log(out);

  // 提供10帧的顶点数据
  const framesData = out;

  return (
    <Canvas
      camera={{ position: new THREE.Vector3(3, 3, 3), fov: 50 }}
      style={{ width: "100vw", height: "100vh" }}
    >
      <Suspense fallback={null}>
        <ambientLight intensity={0.5} />
        <spotLight
          position={[5, 5, 5]}
          angle={0.3}
          intensity={2}
          penumbra={1}
        />
        <PlyModel url={actor1ply} frames={framesData} />
        <OrbitControls />
      </Suspense>
    </Canvas>
  );
}

export default PlyDemo3;
